package rmi;

import service.ClientService._stub.AssessHotelService_stub;
import service.OrderService._stub.BrowseOrderService_stub;
import service.OrderService._stub.BrowseUnfilledOrderService_stub;
import service.ManageService._stub.ChangeHotelInfoService_stub;
import service.OrderService._stub.CheckOrderService_stub;
import service.OrderService._stub.ExceptionOrderService_stub;
import service.OrderService._stub.ExecutionService_stub;
import service.OrderService._stub.HandleExceptionOrderService_stub;
import service.StrategyService._stub.HotelStrategyService_stub;
import service.ManageService._stub.InfoService_stub;
import service.LoginService._stub.LoginService_stub;
import service.ManageService._stub.MemberShipService_stub;
import service.ClientService._stub.OrderHotelService_stub;
import service.ManageService._stub.RechargeService_stub;
import service.ManageService._stub.RegisterMemberService_stub;
import service.ClientService._stub.SearchHotelService_stub;
import service.ManageService._stub.UpdateHotelService_stub;
import service.UpdateService._stub.UpdateService_stub;
import service.ManageService._stub.UserManagementService_stub;
import service.StrategyService._stub.WebsiteStrategyService_stub;
import service.OrderService._stub.WithdrawOrderService_stub;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Map;

/**
 * Created by Dell on 2016/10/25.
 */
public class RMIHelper {
    private Remote reg;
    private InetAddress addr;
    private String hostAddr;
    private String hostName;

    private static Map<String,Class<?extends Serializable>> nameMap=new HashMap<String, Class<? extends Serializable>>();
    private boolean isStarted;

    static {
        nameMap.put("AssessHotelService",AssessHotelService_stub.class);
        nameMap.put("BrowseOrderService", BrowseOrderService_stub.class);
        nameMap.put("BrowseUnfilledOrderService",BrowseUnfilledOrderService_stub.class);
        nameMap.put("ChangeHotelInfoService",ChangeHotelInfoService_stub.class);
        nameMap.put("CheckOrderService",CheckOrderService_stub.class);
        nameMap.put("ExceptionOrderService",ExceptionOrderService_stub.class);
        nameMap.put("ExecutionService",ExecutionService_stub.class);
        nameMap.put("HandleExceptionOrderService",HandleExceptionOrderService_stub.class);
        nameMap.put("HotelStrategyService",HotelStrategyService_stub.class);
        nameMap.put("InfoService",InfoService_stub.class);
        nameMap.put("LoginService",LoginService_stub.class);
        nameMap.put("MemberShipService",MemberShipService_stub.class);
        nameMap.put("OrderHotelService",OrderHotelService_stub.class);
        nameMap.put("RechargeService",RechargeService_stub.class);
        nameMap.put("RegisterMemberService",RegisterMemberService_stub.class);
        nameMap.put("SearchHotelService",SearchHotelService_stub.class);
        nameMap.put("UpdateHotelService",UpdateHotelService_stub.class);
        nameMap.put("UpdateService",UpdateService_stub.class);
        nameMap.put("UserManagementService",UserManagementService_stub.class);
        nameMap.put("WebsiteStrategyService",WebsiteStrategyService_stub.class);
        nameMap.put("WithdrawOrderService",WithdrawOrderService_stub.class);

    }
    public RMIHelper(){
        try {
            addr=InetAddress.getLocalHost();
            hostAddr=addr.getHostAddress();
            hostName=addr.getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public void startServer() {
        new Server().start();
    }

    public void stopServer() {
        try {
            UnicastRemoteObject.unexportObject(reg, true);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        isStarted = false;
    }

    public String getHostAddr() {
        return this.hostAddr;
    }

    public String getHostName() {
        return this.hostName;
    }

    public boolean isStarted() {
        return this.isStarted;
    }

    private class Server extends Thread {

        @Override
        public void run() {
            try {
                SMRMISocket smrmiSocket=new SMRMISocket();
                try {
                    RMISocketFactory.setSocketFactory(smrmiSocket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                reg = LocateRegistry.createRegistry(RMIConfig.getServerPort());
                String prefix = "rmi://" + hostAddr + ":" + RMIConfig.getServerPort() + "/";
                System.out.println(hostAddr);

                for (Entry<String, Class<? extends Serializable>> entry : nameMap.entrySet()) {
                    String name = entry.getKey();
                    Class<? extends UnicastRemoteObject> clazz = (Class<? extends UnicastRemoteObject>) entry.getValue();
                    UnicastRemoteObject proxy = clazz.newInstance();
                    Naming.rebind(prefix+name, proxy);
                }
                isStarted=true;

            } catch (RemoteException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }


        }
    }

}
